/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package rs232picjava;

/**
 *
 * @author Alan Carlos
 */
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.TooManyListenersException;
import gnu.io.*;
import java.io.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class PortaSerial implements Runnable ,SerialPortEventListener {

    static final int BAUDRATE = 9600;
     
    SerialPort port;
    CommPortIdentifier portId;
    BufferedInputStream is;  // for demo purposes only. A stream would be more typical.
    //BufferedOutputStream os;
    PrintStream os;
    Thread readThread;
    JanelaPrincipal janela;
    public PortaSerial(JanelaPrincipal janela) {
        this.janela = janela;
        portId = null;  // will be set if port found
        port = null;
        is = null;
        os = null;
        findPort("COM1");
        acquirePort();
        initializeSerialPort();
        try {
            port.addEventListener(this);
            port.notifyOnDataAvailable(true);
            //  port.addEventListener(new SerialListener());
        } catch (TooManyListenersException ex) {
            ex.printStackTrace();
        }
       // readThread = new Thread(this);
       // readThread.start();
    }


    public void findPort(String wantedPortName) {
        Enumeration portIdentifiers = CommPortIdentifier.getPortIdentifiers();
        while (portIdentifiers.hasMoreElements()) {
            CommPortIdentifier pid = (CommPortIdentifier) portIdentifiers.nextElement();
            if (pid.getPortType() == CommPortIdentifier.PORT_SERIAL
                    && pid.getName().equals(wantedPortName)) {
                portId = pid;
                break;
            }
        }
        if (portId == null) {
            System.err.println("Não foi possível encontrar a porta serial " + wantedPortName);
            System.exit(1);
        }
    }

    public void acquirePort() {
        // Use port identifier for acquiring the port

        try {
            port = (SerialPort) portId.open(
                    "Rs232picjava", // Name of the application asking for the port 
                    10000 // Wait max. 10 sec. to acquire port
                    );
        } catch (PortInUseException e) {
            System.err.println("Porta já em uso: " + e);
            System.exit(1);
        }
    }

    public void initializeSerialPort() {
        try {
            port.setSerialPortParams(
                    BAUDRATE,
                    SerialPort.DATABITS_8,
                    SerialPort.STOPBITS_1,
                    SerialPort.PARITY_NONE);
        } catch (UnsupportedCommOperationException ex) {
            System.err.println("Operação de comunicação não suportada");
        }

        try {
            //is = new BufferedInputStream(port.getInputStream());
            is = new BufferedInputStream(port.getInputStream());
        } catch (IOException e) {
            System.err.println("Não foi possível abrir o fluxo de leitura. Somente Escrita");
            is = null;
        }
        try {
            //
            // New Linux systems rely on Unicode, so it might be necessary to
            // specify the encoding scheme to be used. Typically this should
            // be US-ASCII (7 bit communication), or ISO Latin 1 (8 bit
            // communication), as there is likely no modem out there accepting
            // Unicode for its commands. An example to specify the encoding
            // would look like:
            //
            //     os = new PrintStream(port.getOutputStream(), true, "ISO-8859-1");
            //
            os = new PrintStream(port.getOutputStream(), true);
        

        } catch (IOException ex) {
            System.err.println("Não foi possível abrir o fluxo de escrita. Somente Leitura");
            os = null;
        }

/*
        if (is != null) {
            try {
                is.close();
            } catch (IOException ex) {
                System.err.println("Não foi possível fechar " + is.toString());
            }
        }
        if (os != null) {
            try {
                os.close();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        if (port != null) {
            port.close();
        }*/
    }

    public void writeSerial(char data) {
       // try {
            
            os.print(data);
            os.flush();
        //} catch (IOException ex) {
    //        ex.printStackTrace();
      //  }
    }
    
    public void writeSerial(String strdata) {
       // try {
            char datachar[] = strdata.toCharArray();
            for(char data: datachar ){
            os.print(data);
            os.flush();
            }
        //} catch (IOException ex) {
    //        ex.printStackTrace();
      //  }
    }

    private void dataAvailable() {
        byte[] readBuffer = new byte[20];

        try {
            while (is.available() > 0) {
                int numBytes = is.read(readBuffer);
            }
            String dado = new String(readBuffer).trim();
            System.out.print(dado);// converte em string de acordo com a tabela ascii
            janela.controlTabela(dado);
        } catch (IOException e) {
            e.printStackTrace();
        }
        
    }

    @Override
    public void serialEvent(SerialPortEvent event) {
    
        switch (event.getEventType()) {
            case SerialPortEvent.BI:
            case SerialPortEvent.OE:
            case SerialPortEvent.FE:
            case SerialPortEvent.PE:
            case SerialPortEvent.CD:
            case SerialPortEvent.CTS:
            case SerialPortEvent.DSR:
            case SerialPortEvent.RI:
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
                break;
            case SerialPortEvent.DATA_AVAILABLE:
                dataAvailable();
                break;
        }
    }

    @Override
    public void run() {
        try {
      Thread.sleep(20000);
    } catch (InterruptedException e) {
    }
    }
}
